/*
MIT License

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/stars
*/

#include "simodo/module/HardModule.h"

#include <cassert>

namespace simodo::module
{
    HardModule::HardModule(std::function<ExtModuleFactory_t> creator, interpret::Interpret_interface * interpret)
    : _creator(creator) 
    , _interpret(interpret)
    {
        assert(creator);
        _modules.push_back(creator(interpret));
        assert(_modules.back());
    }

    version_t HardModule::version() const 
    { 
        return _modules[0]->version(); 
    }

    variable::Object HardModule::instantiate(std::shared_ptr<Module_interface> /*module_object*/)
    {
        if (_modules.size() == 1) {
            _modules.push_back(std::shared_ptr<Module_interface>());
            /// \todo Пересмотреть странную передачу самого себя в свой же метод.
            /// PVS Studio: warn V678 An object is used as an argument to its own method.
            /// Consider checking the first actual argument of the 'instantiate' function.
            return _modules[0]->instantiate(_modules[0]);
        }

        size_t last_module_index = _modules.size() - 1;
        _modules[last_module_index] = _creator(_interpret);
        _modules.push_back(std::shared_ptr<Module_interface>());
        /// \todo Пересмотреть странную передачу самого себя в свой же метод.
        /// PVS Studio: warn V678 An object is used as an argument to its own method.
        /// Consider checking the first actual argument of the 'instantiate' function.
        return _modules[last_module_index]->instantiate(_modules[last_module_index]);
    }
}
